package com.videoaggre.zcl.ui.activity

import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.text.Html
import android.util.Log
import androidx.core.text.HtmlCompat
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import com.videoaggre.zcl.R
import com.videoaggre.zcl.utils.Logger
import kotlinx.android.synthetic.main.activity_web_socket.*
import okhttp3.*
import okhttp3.internal.ws.RealWebSocket
import okhttp3.logging.HttpLoggingInterceptor
import okio.ByteString
import java.lang.ref.WeakReference
import java.util.concurrent.TimeUnit

class WebSocketActivity : FragmentActivity(R.layout.activity_web_socket) {
    private var mWebSocketUtils: WebSocketUtils? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mWebSocketUtils = WebSocketUtils(this, "ws://121.40.165.18:8800", object : WebSocketListener() {
            override fun onOpen(webSocket: WebSocket, response: Response) {
                Logger.e("连接成功")
                mWebSocketUtils?.send("连接成功-发送消息")
            }

            override fun onMessage(webSocket: WebSocket, bytes: ByteString) {
                Logger.e("onMessageByteString==>${bytes}")
            }

            override fun onMessage(webSocket: WebSocket, text: String) {
                Logger.e("onMessageString==>${text}")
                tvTest.append(HtmlCompat.fromHtml(text, HtmlCompat.FROM_HTML_MODE_LEGACY))
                tvTest.append("\n")
            }
        })
    }
}

/**
 * 超简单设计，就在activity中开启
 */
class WebSocketUtils(owner: LifecycleOwner, private var url: String, private val listener: WebSocketListener) : WebSocketListener(), DefaultLifecycleObserver {
    companion object {
        private const val DEFAULT_HEART_TIME: Long = 60//默认心跳时间

        private const val TAG: String = "WebSocketLog"//日志抬头
        private const val READ_TIMEOUT: Long = 30//读取超时
        private const val WRITE_TIMEOUT: Long = 30//写入超时
        private const val CONNECT_TIMEOUT: Long = 30//连接超时
        private const val PING_INTERVAL: Long = 30//ping
        private const val WHAT_HEART: Int = 0//handler-what
        private const val WHAT_ON_MESSAGE_STRING: Int = 1//onMessage String
        private const val WHAT_ON_MESSAGE_BYTE_STRING: Int = 2//onMessage ByteString

        private class WithoutLeakHandler(wsu: WebSocketUtils) : Handler(Looper.getMainLooper()) {
            private val mWsu: WeakReference<WebSocketUtils> = WeakReference(wsu)
            override fun handleMessage(msg: Message) {
                when (msg.what) {
                    WHAT_HEART -> mWsu.get()?.apply {
                        send(heartMessage)
                        msg.target.sendEmptyMessageDelayed(WHAT_HEART, heartTime)
                    }
                    WHAT_ON_MESSAGE_STRING -> mWsu.get()?.apply { (msg.obj as WebSocketMessageString).apply { listener.onMessage(webSocket, text) } }
                    WHAT_ON_MESSAGE_BYTE_STRING -> mWsu.get()?.apply { (msg.obj as WebSocketMessageByteString).apply { listener.onMessage(webSocket, bytes) } }
                }
            }
        }
    }

    private var handler: Handler = WithoutLeakHandler(this)
    private var webSocket: RealWebSocket
    private val okHttpClient: OkHttpClient
    var heartMessage: String = ""//心跳消息
    var heartTime: Long = DEFAULT_HEART_TIME * 1000//心跳时间，默认1分钟

    init {
        owner.lifecycle.addObserver(this)
        val interceptor = HttpLoggingInterceptor { Log.e(TAG, it) }
        interceptor.level = HttpLoggingInterceptor.Level.BODY
        okHttpClient = OkHttpClient.Builder()
            .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)//设置读取超时时间
            .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)//设置写的超时时间
            .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)//设置连接超时时间
            .pingInterval(PING_INTERVAL, TimeUnit.SECONDS)
            .retryOnConnectionFailure(true)
            .addInterceptor(interceptor)
            .build()
        val request: Request = Request.Builder().url(url).build()
        //创建webSocket
        webSocket = okHttpClient.newWebSocket(request, this) as RealWebSocket
    }

    //发送方法
    fun send(message: String) {
        val isSend = webSocket.send(message)
        Log.d(TAG, "send-->isSend:$isSend message:$message")
    }

    override fun onMessage(webSocket: WebSocket, bytes: ByteString) {
        handler.sendMessage(Message.obtain().apply {
            what = WHAT_ON_MESSAGE_BYTE_STRING
            obj = WebSocketMessageByteString(webSocket, bytes)
        })
    }

    override fun onMessage(webSocket: WebSocket, text: String) {
        handler.sendMessage(Message.obtain().apply {
            what = WHAT_ON_MESSAGE_STRING
            obj = WebSocketMessageString(webSocket, text)
        })
    }

    override fun onOpen(webSocket: WebSocket, response: Response) = listener.onOpen(webSocket, response)
    override fun onClosed(webSocket: WebSocket, code: Int, reason: String) = listener.onClosed(webSocket, code, reason)
    override fun onClosing(webSocket: WebSocket, code: Int, reason: String) = listener.onClosing(webSocket, code, reason)
    override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
        listener.onFailure(webSocket, t, response)
    }

    fun reConnect(url: String) {
        webSocket.cancel()
        val request: Request = Request.Builder().url(url).build()
        webSocket = okHttpClient.newWebSocket(request, listener) as RealWebSocket
        this.url = url
    }

    fun reConnect() = reConnect(url)
    fun cancel() = webSocket.cancel()

    fun startHeart(heartMessage: String, current: Long) {
        this.heartMessage = heartMessage
        heartTime = current
        handler.sendEmptyMessage(WHAT_HEART)
    }

    fun endHeart() = handler.removeMessages(WHAT_HEART)

    override fun onDestroy(owner: LifecycleOwner) {
        owner.lifecycle.removeObserver(this)
        endHeart()
        handler.removeCallbacks { }
        webSocket.cancel()
        okHttpClient.dispatcher.executorService.shutdown()
        Logger.e("页面关闭，释放资源")
    }
}

internal class WebSocketMessageString(val webSocket: WebSocket, val text: String)
internal class WebSocketMessageByteString(val webSocket: WebSocket, val bytes: ByteString)

object WebSocketMessageHandle {

}